from django.http import JsonResponse
from django.shortcuts import render
from django.views import View
import json

# Create your views here.
from books.models import BookInfo, HeroInfo
# 导入自定义序列化器
from books.serializers import BookSerialzier, HeroSerialzier


class BooksView(View):

    def post(self, request):
        """
           保存图书
       :param request:
       :return:
        """
        # 1、前端传递保存图书的数据 json接受
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        # 2、验证数据
        ser = BookSerialzier(data=dict_data)
        # is_valid 序列化器提供的验证方法 raise_exception=True 的作用是，验证失败抛出异常
        try:
            ser.is_valid(raise_exception=True)
        except Exception as e:
            print(e)
            return JsonResponse({"error": '数据验证失败'})
        # # errors 获取验证的信息内容  数据验证成返回空字典{}
        # print(ser.errors)
        # # 在保存数据之前需要对验证内容进行判断
        # if ser.errors:
        #     # ser.errors有数据，说明验证失败，需要进行返回
        #     return JsonResponse({'error': ser.errors})

        # 3、保存数据
        # 获取验证成功的字段数据进行保存 validated_data
        data = ser.validated_data
        # 调用序列化器封装的保存业务逻辑
        ser.save()
        # 4、返回结果
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中

        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)

    def get(self, request):
        """
                获取图书
               :param request:
               :return:
        """
        books = BookInfo.objects.all()
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中,在返回多个数据时，需要额外增加一个many=true的参数
        ser = BookSerialzier(books, many=True)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse({'books': ser.data})


class BookView(View):

    def delete(self, request, id):
        """
             删除一本图书
         :param request:
         :param pk: 图书id
         :return:
         """
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400'}, status=400)

        # 逻辑删除
        book.is_delete = True
        book.save()
        # 物理删除
        # book.delete()
        return JsonResponse({})

    def put(self, request, id):
        """
            更新一本图书
        :param request:
        :param pk: 图书id
        :return:
        """
        # 查询更新的图书
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)
        # 获取更新的字段
        json_data = request.body.decode()
        dict_data = json.loads(json_data)
        # 验证数据
        # 更新业务中，序列化器初始化是除了要传递验证字段外，还要传递要更新的数据对象
        ser = BookSerialzier(book, data=dict_data)
        try:
            ser.is_valid(raise_exception=True)
        except:
            return JsonResponse({'error': '字段验证失败'}, status=400)
        # 更新数据
        # 调用序列化器封装的update方法 save方法通过序列化器初始化是是否传递数据对象来确定调用cerate方法还是update方法，有数据对象调用update方法
        ser.save()
        # 返回结果
        return JsonResponse(ser.data)

    def get(self, request, id):
        """
            获取一本图书
        :param request:
        :param pk:  图书id
        :return:
        """
        try:
            book = BookInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)

        return JsonResponse({
            'id': book.id,
            'btitle': book.btitle,
            'bpub_date': book.bpub_date,
            'bread': book.bread
        })


class HerosView(View):

    def get(self, request):
        """
                获取所有英雄
               :param request:
               :return:
        """
        heros = HeroInfo.objects.all()
        # 使用序列化器进行序列化操作
        # 初始化生成序列化器对象  将需要进行数据构建的对象传递到序列化器中,在返回多个数据时，需要额外增加一个many=true的参数
        ser = HeroSerialzier(heros, many=True)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse({'heros': ser.data})


class HeroView(View):

    def get(self, request, id):
        """
            获取一本英雄
        :param request:
        :param pk:  图书id
        :return:
        """
        try:
            hero = HeroInfo.objects.get(id=id)
        except:
            return JsonResponse({'code': '400', 'message': '数据不存在'}, status=400)
        ser = HeroSerialzier(hero)
        # 通过序列化器对象的data方法获取构造好的返回结果
        return JsonResponse(ser.data)
